/*
 * COPYRIGHT:	2010 Christopher Smith, licenced under the GNU GPL v2; see COPYING in the top level directory
 * PROJECT:		sdedit
 * FILE:		auto_array.cpp
 * PURPOSE:		automatic (C++ semantics) byte buffer container
 *				
 */

struct auto_buffer : auto_array<unsigned char>
{
	template <class T> T *append(T const *x, size_t length)
	{
		if(!x && !length)
			return c_cast<T *>(ptr);

		//void *ret = ptr + ct;

		increase_ct(ct + length);

		void *ret = ptr + ct - length;

		memcpy(ret, x, length);

		return c_cast<T *>(ret);
	}

	template <class T> T *append_empty(size_t length)
	{
		if(!sizeof(T))
			return c_cast<T *>(ptr);

		//void *ret = ptr + ct;

		increase_ct(ct + length);

		void *ret = ptr + ct - length;

		memset(ret, 0, length);

		return c_cast<T *>(ret);
	}

	template <class T> T *append_szpod(T const *x)
	{
		return append(x, auto_szpod_length<T>(x));
	}

	template <class T> T *append_szpod(auto_szpod<T> const &x)
	{
		return append(x.get(), auto_szpod_length<T>(x.get()));
	}

	template <class T> T *append(T const &x)
	{
		return append(&x, sizeof(T));
	}

	template <class T> T *append_empty()
	{
		return append_empty<T>(sizeof(T));
	}

	template <class T> auto_take<T> release_as()
	{
		return auto_take<T>(c_cast<T *>(release_unsafe()));
	}

	template <class T> T *get_as()
	{
		return c_cast<T *>(ptr);
	}
};

template <class T> union ptr_buffer
{
	T *data;
	size_t pos;

	ptr_buffer() :
		data(0)
	{}

	ptr_buffer(T *data) :
		data(data)
	{}

	ptr_buffer(size_t pos) :
		pos(pos)
	{}
};